package com.leyou.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.JSONPObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.transform.Source;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: quan
 * @create: 2018-04-24 17:20
 **/
public class JsonUtils {

    public static final ObjectMapper mapper = new ObjectMapper();

    private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

    public static String toString(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj.getClass() == String.class) {
            return (String) obj;
        }
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error("json序列化出错：" + obj, e);
            return null;
        }
    }

    public static <T> T toBean(String json, Class<T> tClass) {
        try {
            return mapper.readValue(json, tClass);
        } catch (IOException e) {
            logger.error("json解析出错：" + json, e);
            return null;
        }
    }

    public static <E> List<E> toList(String json, Class<E> eClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
        } catch (IOException e) {
            logger.error("json解析出错：" + json, e);
            return null;
        }
    }

    public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
        } catch (IOException e) {
            logger.error("json解析出错：" + json, e);
            return null;
        }
    }

    public static <T> T nativeRead(String json, TypeReference<T> type) {
        try {
            return mapper.readValue(json, type);
        } catch (IOException e) {
            logger.error("json解析出错：" + json, e);
            return null;
        }
    }

    public static void main(String[] args) {
        User jack = new User("Jack", 21);
        //序列化 bean --> json
        String json = toString(jack);
        System.out.println(json);

        //序列化 list --> json
        List<User> list = Arrays.asList(jack, new User("Rose", 18));
        json = toString(list);
        System.out.println(json);

        //序列化 map --> json
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("jack", jack);
        map.put("list", list);
        String maop1 = toString(map);
        System.out.println(maop1);//

        //反序列化  json-->  bean
        String str = "{\"name\":\"jack\",\"age\":21}";
        User user = toBean(str, User.class);
        System.out.println(user);

        //反序列化  json --> list
        str = "[{\"name\":\"jack\",\"age\":21},{\"name\":\"Rose\",\"age\":15}]";
        List<User> list1 = toList(str, User.class);
        System.out.println(list1);

        //反序列化  json --> map
        str = "{\"name\":\"jack\",\"age\":21}";
        Map<String, String> toMap = toMap(str, String.class, String.class);
        System.out.println(toMap);

        // 变态版 反序列变化  json --> map
        str = "{\"heima97\":[{\"name\":\"Jack\",\"age\":21},{\"name\":\"Rose\",\"age\":18}],\"heima98\":[{\"name\":\"Jack\",\"age\":21},{\"name\":\"Rose\",\"age\":18}]}";
        Map<String, List<User>> nativeRead = nativeRead(str, new TypeReference<Map<String, List<User>>>() {
        });
        System.out.println(nativeRead);
    }


    @Data
    @AllArgsConstructor   //有参构造
    @NoArgsConstructor    //无参构造
    static class User {
        String name;
        int age;
    }
}
